/**
 * 迭代器模式提前终止迭代器
 */
;(function () {
    class Counter {
        constructor(limit) {
            this.limit = limit
        }

        [Symbol.iterator]() {
            let count = 1
            let limit = this.limit

            return {
                next() {
                    if (count <= limit) {
                        return {done: false, value: count++}
                    } else {
                        return {done: true}
                    }
                },
                return() {
                    console.log("Exiting early")
                    return {dong: true}
                }
            }
        }
    }

    let counter1 = new Counter(5)

    for (let i of counter1) {
        if (i > 2) {
            break;
        }
        console.log(i)
    }

    console.log("counter1=============")

    let counter2 = new Counter(5);
    try {
        for (let i of counter2) {
            if (i > 2) {
                throw 'err';
            }
            console.log(i)
        }
    } catch (e) {
    }
    // 1
    // 2
    // Exiting early

    console.log("=========")
    let counter3 = new Counter(5);
    let [a, b] = counter3;
    console.log(a, b)
    // Exiting early
})()

/**
 * 如果迭代器没有关闭，则还可以继续从上次离开的地方继续迭代。
 */
;(function () {
    let a = [1, 2, 3, 4, 5];
    let iter =  a[Symbol.iterator]()

    for (let i of iter) {
        console.log(i);
        if (i > 2) {
            break
        }
    }
    // 1
    // 2
    // 3

    for (let i of iter) {
        console.log(i);
    }
    // 4
    // 5
    console.log("===========")
})()

/**
 * 为 return()方法是可选的，所以并非所有迭代器都是可关闭的。
 * 要知道某个迭代器是否可关闭，可以测试这个迭代器实例的 return 属性是不是函数对象。
 * 不过，仅仅给一个不可关闭的迭代器增加这个方法并不能让它变成可关闭的。
 * 这是因为调用 return()不会强制迭代器进入关闭状态。即便如此，return()方法还是会被调用。
 */
;(function () {
    let a = [1, 2, 3, 4, 5];
    let iter = a[Symbol.iterator]();
    iter.return = function () {
        console.log('Exiting early');
        return {done: true};
    }

    for (let i of iter) {
        console.log(i);
        if (i > 2) {
            break
        }
    }
    // 1
    // 2
    // 3
    // 提前退出

    for (let i of iter) {
        console.log(i);
    }
    // 4
    // 5
})()